﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cn.Cellula.Module.Stat.Model;
using System.Xml;
using System.Data;
using Cn.Cellula.Client;
using System.Collections;

namespace Cn.Cellula.Module.Stat.FusionCharts {
    public class FChartBuilder {
        private ModVStatEO _Stat;
        private IList<ModVStatSeriesEO> _SeriesList;
        private XmlDocument _Doc;
        public FChartBuilder(ModVStatEO rStat, IList<ModVStatSeriesEO> rSeriesList) {
            _Stat = rStat;
            _SeriesList = rSeriesList;
            _Doc = new XmlDocument();
            _Doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\" ?><chart></chart>");
            SetChartAttr();
        }

        #region Chart Xml 方法
        private XmlElement AppendElement(XmlElement rParent, String rNodeName) {
            XmlElement el = _Doc.CreateElement(rNodeName);
            rParent.AppendChild(el);
            return el;
        }
        private void AppendAttr(XmlElement rNode, String rAttrName, String rAttrValue,String rDefault) {
            if (rNode.Attributes[rAttrName] != null) {
                rNode.Attributes[rAttrName].Value = (String.IsNullOrEmpty(rAttrValue)) ? rDefault : rAttrValue;
            } else {
                XmlAttribute attr = _Doc.CreateAttribute(rAttrName);
                attr.Value = (String.IsNullOrEmpty(rAttrValue)) ? rDefault : rAttrValue;
                rNode.Attributes.Append(attr);
            }
        }

        private void AppendTrend(String rValue, String rLabel, String rColor) {
            //startValue='700000' color='009933' displayvalue='Target'
            XmlElement trend = _Doc.CreateElement("trendLines");
            XmlElement line = _Doc.CreateElement("line");
            trend.AppendChild(line);
            XmlAttribute startValue = _Doc.CreateAttribute("startValue");
            startValue.Value = rValue;
            line.Attributes.Append(startValue);
            XmlAttribute displayValue = _Doc.CreateAttribute("displayValue");
            displayValue.Value = rLabel;
            line.Attributes.Append(displayValue);
            if (!String.IsNullOrEmpty(rColor)) {
                XmlAttribute color = _Doc.CreateAttribute("color");
                color.Value = rColor;
                line.Attributes.Append(color);
            }
            _Doc.DocumentElement.AppendChild(trend);
        }
        private IList<DataItem> Convert(IList<Object> list) {
            IList<DataItem> dilist = new List<DataItem>();
            foreach (Object[] obj in list) {
                DataItem di = new DataItem();
                di.Key = (obj[0] == null) ? "" : obj[0].ToString();
                di.Label = (obj[1] == null) ? "" : obj[1].ToString();
                di.Value = (obj[2] == null) ? "" : obj[2].ToString();
                dilist.Add(di);
            }
            return dilist;
        }
        private void SetChartAttr() {
            AppendAttr(_Doc.DocumentElement, "caption", _Stat.StatName,"Stat");
            AppendAttr(_Doc.DocumentElement, "xAxisName", _Stat.XName,"X");
            AppendAttr(_Doc.DocumentElement, "yAxisName", _Stat.YName,"Y");
            AppendAttr(_Doc.DocumentElement, "showValues", _Stat.IfShowValues + "","1");
            AppendAttr(_Doc.DocumentElement, "numberPrefix", _Stat.NumberPrefix,"");
            AppendAttr(_Doc.DocumentElement, "shownames", "1","");
        }
        #endregion

        #region 构造XML数据
        public String BuildChartXmlContent(IList<DataSet> rData) {
            ChartType ct = (ChartType)Enum.Parse(typeof(ChartType), _Stat.ChartKey.ToString());
            return BuildChartXmlContent(ct, rData);
        }
        public String BuildChartXmlContent(ChartType rChartType, IList<DataSet> rData) {
            if (rChartType == ChartType.MSColumn3D) {
                return BuildMultiColumn3D(rData);
            } else if (rChartType == ChartType.Column3D) {
                return BuildColumn3D(rData);
            } else if (rChartType == ChartType.Line) {
                return BuildLine(rData);
            } else if (rChartType == ChartType.MSLine) {
                return BuildMSLine(rData);
            } else if (rChartType == ChartType.Pie3D) {
                return BuildPie3D(rData);
            } else {
                return "";
            }
        }
        #endregion


        #region 构造不同类型图形的XML数据
        /// <summary>
        /// 构造通用方法，适用于柱图Column,饼图Pie,曲线图Line
        /// </summary>
        /// <param name="rData"></param>
        /// <returns></returns>
        private String BuildCommonData(IList<DataSet> rData) {
            if (rData != null && rData.Count > 0) {//必须有数据
                if (_SeriesList.Count <= 1) {//单列
                    foreach (DataRowView row in rData[0].Tables[0].DefaultView) {
                        XmlElement set = AppendElement(_Doc.DocumentElement, "set");
                        AppendAttr(set, "label", row[_Stat.DataTextField].ToString(), TxtDef.OTHER);
                        AppendAttr(set, "value", row[_Stat.DataValueField].ToString(), "0");
                    }
                } else {//多列
                    XmlElement categories = AppendElement(_Doc.DocumentElement, "categoies");
                    foreach (DataRowView row in rData[0].Tables[0].DefaultView) {
                        XmlElement category = AppendElement(categories, "category ");
                        AppendAttr(category, "label", row[_Stat.DataTextField].ToString(), TxtDef.OTHER);
                    }
                    for (int i = 0; i < _SeriesList.Count; i++) {
                        ModVStatSeriesEO se = _SeriesList[i];
                        XmlElement dataset = AppendElement(_Doc.DocumentElement, "dataset");
                        AppendAttr(dataset, "seriesName", se.SeriesTitle, "Series " + (i + 1));
                        if (!String.IsNullOrEmpty(se.RenderAsValue)) {
                            AppendAttr(dataset, "renderAs", se.RenderAsValue, "");
                        }
                        if (i >= rData.Count) {
                            //如果数据集个数少于Series的个数，跳出循环
                            break;
                        }
                        DataSet ds = rData[i];
                        foreach (DataRowView row in ds.Tables[0].DefaultView) {
                            XmlElement set = AppendElement(dataset, "set");
                            AppendAttr(set, "label", row[_Stat.DataTextField].ToString(), TxtDef.OTHER);
                            AppendAttr(set, "value", row[_Stat.DataValueField].ToString(), "0");
                        }
                    }
                }
            }
            if (!String.IsNullOrEmpty(_Stat.TrendName)) {
                AppendTrend(_Stat.TrendValue + "", _Stat.TrendName, null);
            }
            return _Doc.OuterXml.Replace("\"", "\\\"");
        }

        private String BuildColumn3D(IList<DataSet> rData) {
            return BuildCommonData(rData);
        }
        private String BuildLine(IList<DataSet> rData) {
            return BuildCommonData(rData);
        }
        private String BuildMSLine(IList<DataSet> rData) {
            return BuildCommonData(rData);
        }
        private String BuildPie3D(IList<DataSet> rData) {
            //显示百分比
            AppendAttr(_Doc.DocumentElement, "showPercentageValues", "1", "");
            return BuildCommonData(rData);
        }
        private String BuildMultiColumn3D(IList<DataSet> rData) {
            return BuildCommonData(rData);
        }
        #endregion
    }
}
